﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using 低频天线阵列相控阵信号发生系统SmartFASK12.Controls;
using 低频天线阵列相控阵信号发生系统SmartFASK12.Models;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Rebar;

namespace 低频天线阵列相控阵信号发生系统SmartFASK12.View
{
    public partial class UFrequencyBandTesting : UserControl
    {
        /// <summary>
        /// 是否停止
        /// </summary>
        private bool IsStop = true;
        /// <summary>
        /// 频带测试集合
        /// </summary>
        private List<FrequencyBandTestingModel> _frequencyBandTestings;
        /// <summary>
        /// 频带测试集合显示
        /// </summary>
        private List<FrequencyBandTestingModel> _frequencyBandTestingsShow;
        /// <summary>
        /// 频点图显示
        /// </summary>
        private FrequencyPointModel _frequencyPointModel;
        public UFrequencyBandTesting()
        {
            InitializeComponent();

            Init();
        }

        private void Init()
        {
            formsPlotFFT.Plot.Clear();
            formsPlotFFT.Refresh();
            formsPlotFrequency.Plot.Clear();
            formsPlotFrequency.Refresh();

            dataGridView_FrequencyBandTesting.RowHeadersVisible = false;
            dataGridView_FrequencyBandTesting.AllowUserToAddRows = false;
            formsPlotFFT.Plot.Title("FFT");
            formsPlotFrequency.Plot.Title("频点图");
            label_MagneticField.Text = "0";
            label_Percentage.Text = "0/0";
            progressBar.Value = 0;

            _frequencyBandTestings = new List<FrequencyBandTestingModel>();
            _frequencyBandTestingsShow = new List<FrequencyBandTestingModel>();
            _frequencyPointModel = new FrequencyPointModel();

            if (MPublic.ConfigModel == null)
                return;

            comboBox_Frequency.Text = MPublic.ConfigModel.frequency.ToString();
            comboBox_FrequencyPoint.Text = MPublic.ConfigModel.frequencyPoint3.ToString();
            comboBox_CollectionDuration.Text = MPublic.ConfigModel.collectionDuration3.ToString();
            comboBox_AverageNumber.Text = MPublic.ConfigModel.averageNumber3.ToString();
            comboBox_SensitivityCoefficient.Text = MPublic.ConfigModel.sensitivityCoefficient2.ToString();
            comboBox_AutomaticTestMax.Text = MPublic.ConfigModel.automaticTestMax.ToString();
            comboBox_AutomaticTestMin.Text = MPublic.ConfigModel.automaticTestMin.ToString();
            comboBox_Interval.Text = MPublic.ConfigModel.interval.ToString();
            checkBox_OutputInverted.Checked = MPublic.ConfigModel.outputInverted;

            dataGridView_FrequencyBandTesting.DataSource = new BindingSource(new BindingList<FrequencyBandTestingModel>(_frequencyBandTestings), null);
        }

        /// <summary>
        /// 手动测试
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_ManualTest_Click(object sender, EventArgs e)
        {
            SaveConfig();

            if (_frequencyBandTestingsShow.Count > 0)
            {
                if (_frequencyBandTestingsShow.Where(w => w.frequency == MPublic.ConfigModel.frequency).Count() > 0)
                {
                    MessageBox.Show("当前频率已采集！", "提示");
                    return;
                }

                if (_frequencyBandTestingsShow.Max(m => m.frequency) > MPublic.ConfigModel.frequency)
                {
                    MessageBox.Show("采集频率不能小于之前采集频率！", "提示");
                    return;
                }
            }

            label_MagneticField.Text = "0";

            //进度
            progressBar.Maximum = MPublic.ConfigModel.averageNumber3;
            //进度
            label_Percentage.Text = 0 + "/" + MPublic.ConfigModel.averageNumber3;
            IsStop = false;
            //采集线程
            Thread thread = new Thread(frequencyBandTesting_Thread)
            {
                IsBackground = true,
            };
            thread.Start(true);
        }

        /// <summary>
        /// 自动测试
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_AutomaticTesting_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(richTextBox_signalsequence.Text))
            {
                MessageBox.Show("01输入框不能为空", "提示");
                return;
            }
            SaveConfig();

            if (MPublic.ConfigModel.automaticTestMin >= MPublic.ConfigModel.automaticTestMax)
            {
                MessageBox.Show("最小值不能小于最大值！", "提示");
                return;
            }

            if (_frequencyBandTestingsShow.Count > 0)
            {
                if (_frequencyBandTestingsShow.Max(m => m.frequency) > MPublic.ConfigModel.automaticTestMin)
                {
                    MessageBox.Show("采集频率不能小于之前采集频率！", "提示");
                    return;
                }
            }

            label_MagneticField.Text = "0";
            IsStop = false;
            //进度
            progressBar.Maximum = MPublic.ConfigModel.averageNumber3;
            //进度
            label_Percentage.Text = 0 + "/" + MPublic.ConfigModel.averageNumber3;

            //采集线程
            Thread thread = new Thread(frequencyBandTesting_Thread)
            {
                IsBackground = true,
            };
            thread.Start(false);
        }

        /// <summary>
        /// 清空
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Empty_Click(object sender, EventArgs e)
        {
            Init();
        }

        /// <summary>
        /// 保存Config
        /// </summary>
        private void SaveConfig()
        {

            MPublic.ConfigModel.frequency = Convert.ToDouble(comboBox_Frequency.Text);
            MPublic.ConfigModel.frequencyPoint3 = Convert.ToDouble(comboBox_FrequencyPoint.Text);
            MPublic.ConfigModel.collectionDuration3 = Convert.ToDouble(comboBox_CollectionDuration.Text);
            MPublic.ConfigModel.averageNumber3 = Convert.ToInt32(comboBox_AverageNumber.Text);
            MPublic.ConfigModel.sensitivityCoefficient2 = Convert.ToDouble(comboBox_SensitivityCoefficient.Text);
            MPublic.ConfigModel.automaticTestMax = Convert.ToDouble(comboBox_AutomaticTestMax.Text);
            MPublic.ConfigModel.automaticTestMin = Convert.ToDouble(comboBox_AutomaticTestMin.Text);
            MPublic.ConfigModel.interval = Convert.ToDouble(comboBox_Interval.Text);
            MPublic.ConfigModel.outputInverted = checkBox_OutputInverted.Checked;
            MPublic.ConfigModel.signalsequence = richTextBox_signalsequence.Text;

            MPublic.ConfigModel = MPublic.ConfigModel;
        }

        /// <summary>
        /// 频带测试线程
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private void frequencyBandTesting_Thread(object obj)
        {
            //频率
            double frequency = 0;
            //是否手动
            bool IsHandMovement = Convert.ToBoolean(obj);
            int count = 0;
            //手动
            if (IsHandMovement)
            {
                count = 0;
                frequency = MPublic.ConfigModel.frequency;
            }
            //自动
            else
            {
                double gapValue = MPublic.ConfigModel.automaticTestMax - MPublic.ConfigModel.automaticTestMin;
                count = Convert.ToInt32(gapValue / MPublic.ConfigModel.interval);
            }
            for (int k = 0; k <= count; k++)
            {
                //自动
                if (!IsHandMovement)
                {
                    //反向输出
                    if (MPublic.ConfigModel.outputInverted)
                    {
                        frequency = MPublic.ConfigModel.automaticTestMax - MPublic.ConfigModel.interval * k;
                    }
                    //正向输出
                    else
                    {
                        frequency = MPublic.ConfigModel.automaticTestMin + MPublic.ConfigModel.interval * k;
                    }
                }
                //采集数量
                int samplesPerChannel = (int)(MPublic.ConfigModel.rate * MPublic.ConfigModel.collectionDuration3);

                //数据1
                CalSingalInfo CalSingalInfo1 = MJietiao.Singleton().CalSingalASK(
                    MPublic.ConfigModel.signalFrequency,
                    MPublic.ConfigModel.rate,
                    Convert.ToInt32(frequency),//MPublic.ConfigModel.carrierFrequency1,
                    MPublic.ConfigModel.range1,
                    MPublic.ConfigModel.benchmark1,
                    MPublic.ConfigModel.phase1,
                    MPublic.ConfigModel.dutyCycle,
                    samplesPerChannel,
                    3,
                    MPublic.ConfigModel.signalsequence);

                //数据2
                CalSingalInfo CalSingalInfo2 = MJietiao.Singleton().CalSingalASK(
                    MPublic.ConfigModel.signalFrequency,
                    MPublic.ConfigModel.rate,
                    Convert.ToInt32(frequency),//MPublic.ConfigModel.carrierFrequency1,
                    MPublic.ConfigModel.range2,
                    MPublic.ConfigModel.benchmark2,
                    MPublic.ConfigModel.phase2,
                    MPublic.ConfigModel.dutyCycle,
                    samplesPerChannel,
                    3,
                    CalSingalInfo1.numberSignal,
                    CalSingalInfo1.numberSignals);

                //输出电压
                string msg = MNI.Singleton().OutputOoltage(
                    MPublic.ConfigModel.physicalChannelName,
                    CalSingalInfo1.res.ToArray(),
                    MPublic.ConfigModel.physicalChannelName2,
                    CalSingalInfo2.res.ToArray(),
                    MPublic.ConfigModel.minimumValue,
                    MPublic.ConfigModel.maximumValue,
                    MPublic.ConfigModel.rate,
                    samplesPerChannel);

                if (msg != null)
                {
                    MessageBox.Show(msg, "提示");
                    return;
                }

                for (int i = 0; i < MPublic.ConfigModel.averageNumber3; i++)
                {
                    while (IsStop)
                    {
                        //停止采集
                        MNI.Singleton().Stop();
                        return;
                    }
                    double[] data;
                    if (MPublic.ConfigModel.cjktype == Enums.CollectionCardTypeEnum.Card_4431)
                    {
                        //采集电压
                        data = MNI.Singleton().CollectVoltage(
                        MPublic.ConfigModel.physicalChannelName3,
                        MPublic.ConfigModel.minimumValue,
                        MPublic.ConfigModel.maximumValue,
                        MPublic.ConfigModel.rate,
                        samplesPerChannel,
                         NationalInstruments.DAQmx.AITerminalConfiguration.Pseudodifferential);
                    }
                    else
                    {
                        //采集电压
                        data = MNI.Singleton().CollectVoltage(
                        MPublic.ConfigModel.physicalChannelName3,
                        MPublic.ConfigModel.minimumValue,
                        MPublic.ConfigModel.maximumValue,
                        MPublic.ConfigModel.rate,
                        samplesPerChannel);
                    }
                    if (data == null)
                    {
                        MessageBox.Show("当前为采集到数据", "提示");
                        return;
                    }

                    //FFT计算
                    MDataModel mData = MyMatlab.FFT(data.ToList(), MPublic.ConfigModel.rate);

                    //查询X中频点的索引
                    var frequencyPointIndex = mData.XValues.Select((person, index) => new { index, person }).Where(a => a.person == frequency).FirstOrDefault();

                    double yvalue = -1;
                    if (frequencyPointIndex != null)
                    {
                        //查询Y值
                        yvalue = mData.YValues[frequencyPointIndex.index];
                    }

                    //添加表格
                    _frequencyBandTestings.Add(new FrequencyBandTestingModel()
                    {
                        serialNumber = _frequencyBandTestings.Count + 1,
                        frequency = frequency,
                        measuredVoltage = yvalue,
                        convertedMagneticField = yvalue / MPublic.ConfigModel.sensitivityCoefficient2
                    });
                    BeginInvoke(new Action(() =>
                    {
                        //绘制FFT
                        formsPlotFFT.Plot.Clear();
                        formsPlotFFT.Plot.AddSignalXY(mData.XValues.ToArray(), mData.YValues.ToArray());
                        formsPlotFFT.Plot.AxisAuto();
                        formsPlotFFT.Refresh();

                        //进度
                        label_Percentage.Text = i + "/" + MPublic.ConfigModel.averageNumber3;
                        //进度条
                        progressBar.Value = i;
                    }));
                }
                //停止采集
                MNI.Singleton().Stop();

                //添加表格
                double measuredVoltageAverage = _frequencyBandTestings.Where(w => w.frequency == frequency).Average(a => a.measuredVoltage);
                double convertedMagneticFieldAverage = _frequencyBandTestings.Where(w => w.frequency == frequency).Average(a => a.convertedMagneticField);

                _frequencyBandTestingsShow.Add(new FrequencyBandTestingModel()
                {
                    serialNumber = _frequencyBandTestingsShow.Count + 1,
                    frequency = frequency,
                    measuredVoltage = measuredVoltageAverage,
                    convertedMagneticField = convertedMagneticFieldAverage,
                    measuredVoltages = _frequencyBandTestings.Where(w => w.frequency == frequency).Select(s => s.measuredVoltage).ToList()
                });


                if (MPublic.ConfigModel.outputInverted)
                {
                    _frequencyPointModel.xs.Insert(0, frequency);
                    _frequencyPointModel.ys.Insert(0, convertedMagneticFieldAverage);
                }
                else
                {
                    _frequencyPointModel.xs.Add(frequency);
                    _frequencyPointModel.ys.Add(convertedMagneticFieldAverage);
                }

                BeginInvoke(new Action(() =>
                {
                    label_MagneticField.Text = convertedMagneticFieldAverage.ToString();

                    //添加表格
                    dataGridView_FrequencyBandTesting.DataSource = new BindingSource(new BindingList<FrequencyBandTestingModel>(_frequencyBandTestingsShow), null);

                    //绘制频点图
                    formsPlotFrequency.Plot.Clear();
                    formsPlotFrequency.Plot.AddSignalXY(_frequencyPointModel.xs.ToArray(), _frequencyPointModel.ys.ToArray(), Color.Red);
                    formsPlotFrequency.Plot.AxisAuto();
                    formsPlotFrequency.Refresh();
                }));
            }
        }

        private void formsPlotFrequency_MouseMove(object sender, MouseEventArgs e)
        {
            if (_frequencyPointModel.ys.Count <= 0)
            {
                return;
            }
            /*
             * 3.计算鼠标处的值并通过Label显示
             */
            label6.Visible = false;
            Point mouseLocation = e.Location;
            double xCoordinate = formsPlotFrequency.Plot.GetCoordinateX(mouseLocation.X);
            int xAxis = Math.Abs((int)Math.Round(xCoordinate));
            if (xAxis <= _frequencyPointModel.xs.Max())
            {
                //查询X中频点的索引
                var frequencyPointIndex = _frequencyPointModel.xs.Select((person, index) => new { index, person }).Where(a => a.person == xAxis).FirstOrDefault();
                if (frequencyPointIndex == null) { return; }
                int y = (int)formsPlotFrequency.Plot.GetPixelY(_frequencyPointModel.ys[frequencyPointIndex.index]);
                if (Math.Abs(mouseLocation.Y - y) < 16)
                {
                    label6.Text = "Y:" + _frequencyPointModel.ys[frequencyPointIndex.index]
                        + "\nX:" + xAxis;
                    //调整label到合适位置
                    //mouseLocation.Y += label6.Height;
                    mouseLocation.X += 16;
                    label6.Location = mouseLocation;
                    label6.Visible = true;
                }
            }
        }

        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Export_Click(object sender, EventArgs e)
        {
            if (_frequencyBandTestingsShow.Count <= 0)
            {
                MessageBox.Show("当前没有数据可以导出！", "提示");
                return;
            }

            //对话框
            SaveFileDialog sfd = new SaveFileDialog();
            //设置保存文件对话框的标题
            sfd.Title = "请选择要保存的文件路径";
            //初始化保存目录，默认exe文件目录
            sfd.InitialDirectory = Application.StartupPath;
            //设置保存文件的类型
            sfd.Filter = "EXCEL|*.xlsx|EXCEL|*.xls";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                //获得保存文件的路径
                string filePath = sfd.FileName;
                if (!MExcel.Singleton().ToExportFrequencyBandData(filePath, _frequencyBandTestingsShow))
                {
                    MessageBox.Show("导出数据时发生了异常！", "异常");
                }
            }
        }

        /// <summary>
        /// 停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Stop_Click(object sender, EventArgs e)
        {
            IsStop = true;
        }

        /// <summary>
        /// 信号序列手动输入更改
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void richTextBox_signalsequence_TextChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(richTextBox_signalsequence.Text))
            {
                return;
            }
            Regex r = new Regex("[^0|1]");
            Match m = r.Match(richTextBox_signalsequence.Text);
            if (m.Success)
            {
                //含有不是0或1的字符
                MessageBox.Show("当前输入参数有误！");
                return;
            }
            else
            {
                //都是由0或1的字符
            }

            double OutputTime = MPublic.ConfigModel.rate / MPublic.ConfigModel.numbersignals;
            double ManuallyInputQuantity = Math.Ceiling(MPublic.ConfigModel.signalFrequency * OutputTime);
            label_proportion.Text = richTextBox_signalsequence.Text.Length + "/" + ManuallyInputQuantity;
        }
    }
}
